<?php
/**
 * *********************************************************
 *  KEINOS Data engine class
 * *********************************************************
 */

if(!class_exists('cData')){
    class cData{
        var $rLink;
        var $db_name;
        
        function __destruct(){
            if(is_resource($this->rLink)){
                //トランザクションの終了
                sqlite_query($this->rLink, "commit;");
                //DBのクローズ
                sqlite_close($this->rLink);
            }
            $this->rLink=null;
        }

        /* =================================
            コンストラクター
           ================================= */
        function __construct($sDBName="",$sDBSavePath=""){
            $this->cData($sDBName,$sDBSavePath);
        }

        function cData($sDBName="",$sDBSavePath=""){

            if( !Empty($sDBSavePath) && !dir_exists($sDBSavePath) ){
                die("データの保存先が無効です。");
            }

            //保存先ディレクトリの設定
            switch(TRUE){
                case( dir_exists($sDBSavePath) ):
                    $sPath_temp = realpath($sDBSavePath)    . DIRECTORY_SEPARATOR; break;
                case( dir_exists("./_data/") ):
                    $sPath_temp = realpath("./_data/")      . DIRECTORY_SEPARATOR; break;
                case( dir_exists("./_lib/_data/") ):
                    $sPath_temp = realpath("./_lib/_data/") . DIRECTORY_SEPARATOR; break;
                default:
                    if(!defined('KEINOS_DATA_DIR')) { die('データの保存先ディレクトリ(KEINOS_DATA_DIR)が定義されていません。'); }
                    $sPath_temp = realpath(KEINOS_DATA_DIR) . DIRECTORY_SEPARATOR; break;
            }

            //DBの基本設定
            $sDBName = Empty($sDBName) ? "database_default" : "database_" . rawurlencode($sDBName);
            $sPath = $sPath_temp . $sDBName . ".db";
            $bIsNewDB = !file_exists($sPath); //新規DBの場合テーブルを作成する必要があるため

            $this->db_name  = $sDBName;

            //DBのオープン
            $this->rLink = sqlite_open($sPath, 0666, $sqliteerror);

            if (!$this->rLink) { die("データベースの接続失敗です。<hr><pre style='text-align:left;font-family:monospace; white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;white-space: pre-wrap;word-wrap: break-word;'>{$sqliteerror}</pre>"); }

            //テーブルの作成（新規の場合）
            if($bIsNewDB){
                $sql = "CREATE TABLE keinos_db(id TEXT PRIMARY KEY,value TEXT,time_create int,time_update int)";
                $bResult = sqlite_query($this->rLink, $sql, SQLITE_ASSOC, $sqliteerror);
                if (!$bResult) { die("クエリーエラー：データベースのテーブル作成失敗です。<hr><pre style='text-align:left;font-family:monospace; white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;white-space: pre-wrap;word-wrap: break-word;'>{$sqliteerror}</pre>"); }
            }

            sqlite_query($this->rLink,"begin;"); //トランザクションの明示

        }

        /* =================================
            データ保存処理
           ================================= */
        function save($sDataID,$mData){
            if(!is_resource($this->rLink)){ $this->cData($this->db_name);}

            $sKey    = rawurlencode($sDataID);
            $sData   = sqlite_escape_string(serialize($mData));

            //上書きかのチェック
            $sSQL = "SELECT * FROM keinos_db WHERE id='{$sKey}'; ";
            $rResult = sqlite_query($this->rLink,$sSQL, SQLITE_BOTH, $sqliteerror);
            //データの上書き
            if(sqlite_num_rows($rResult)>0){
                $iTime = time();
                $sSQL  = "UPDATE keinos_db SET value='{$sData}',time_update={$iTime} WHERE id='{$sKey}';";
            }
            //データの追加
            else{
                $iTime = time();
                $sSQL    = "INSERT INTO keinos_db(id,value,time_create,time_update) VALUES('{$sKey}','{$sData}',{$iTime},{$iTime});";
            }
            $bResult = sqlite_exec($this->rLink, $sSQL, $sqliteerror);
            
            return $bResult;
            
        }

        function load($sDataID){
            if(!is_resource($this->rLink)){ $this->cData($this->db_name);}

            //データの取得
            $sKey    = rawurlencode($sDataID);
            $sSQL    = "SELECT id, value FROM keinos_db WHERE id='{$sKey}';";
            $rResult = sqlite_query($this->rLink, $sSQL, SQLITE_BOTH, $sqliteerror);
            
            if(sqlite_num_rows($rResult)==1){
                $row = sqlite_fetch_array($rResult, SQLITE_ASSOC);
                $mResult = unserialize($row['value']);
            }
            else{
                $mResult = FALSE;
            }
            
            return $mResult;

        }

        function get_list(){
            if(!is_resource($this->rLink)){ $this->cData($this->db_name);}

            //データの取得
            $sSQL    = "SELECT id FROM keinos_db;";
            $rResult = sqlite_query($this->rLink, $sSQL, SQLITE_BOTH, $sqliteerror);
            
            for ($i=0;$i<sqlite_num_rows($rResult); $i++){
                $row = sqlite_fetch_array($rResult, SQLITE_ASSOC);
                $mResult[] = rawurldecode($row['id']);
            }

            return $mResult;

        }

        function dump($sDataID=""){
            if(!is_resource($this->rLink)){ $this->cData($this->db_name);}

            if(Empty($sDataID)){
                //全データの取得
                $sSQL    = "SELECT * FROM keinos_db;";
            }
            else{
                //データの取得
                $sKey    = rawurlencode($sDataID);
                $sSQL    = "SELECT * FROM keinos_db WHERE id='{$sKey}';";
            }

            $rResult = sqlite_query($this->rLink, $sSQL, SQLITE_BOTH, $sqliteerror);
            
            for ($i=0;$i<sqlite_num_rows($rResult); $i++){
                $row = sqlite_fetch_array($rResult, SQLITE_ASSOC);
                $row['id']    = rawurldecode($row['id']);
                $row['value'] = unserialize($row['value']);
                $mResult[] = $row;
            }

            return $mResult;

        }

        function delete($sDataID){
            if(!is_resource($this->rLink)){ $this->cData($this->db_name);}

            //データの削除
            $sKey    = rawurlencode($sDataID);
            $sSQL    = "DELETE FROM keinos_db WHERE id='{$sKey}';";
            $bResult = sqlite_exec($this->rLink, $sSQL, $sqliteerror);
            
            return (!$bResult) ? FALSE : TRUE;
        }

        function unlink($sDBName=""){
            if(is_resource($this->rLink)){ $this->__destruct();}

            //DBの基本設定
            $sDBName = Empty($sDBName) ? $this->db_name : rawurlencode($sDBName);
            $sPath = KEINOS_DATA_DIR . $sDBName . ".db";

            if(File_Exists($sPath)){
                return rename($sPath,$sPath.".deleted");
            }
            else{
                return FALSE;
            }

        }

        function get_time_create($sDataID){
            if(!is_resource($this->rLink)){ $this->cData($this->db_name);}

            //データの取得
            $sKey    = rawurlencode($sDataID);
            $sSQL    = "SELECT time_create FROM keinos_db WHERE id='{$sKey}';";
            $rResult = sqlite_query($this->rLink, $sSQL, SQLITE_BOTH, $sqliteerror);
            
            if(sqlite_num_rows($rResult)==1){
                $row = sqlite_fetch_array($rResult, SQLITE_ASSOC);
                $mResult = $row['time_create'];
            }
            else{
                $mResult = FALSE;
            }
            
            return $mResult;
        }

        function get_time_update($sDataID){
            if(!is_resource($this->rLink)){ $this->cData($this->db_name);}

            //データの取得
            $sKey    = rawurlencode($sDataID);
            $sSQL    = "SELECT time_update FROM keinos_db WHERE id='{$sKey}';";
            $rResult = sqlite_query($this->rLink, $sSQL, SQLITE_BOTH, $sqliteerror);
            
            if(sqlite_num_rows($rResult)==1){
                $row = sqlite_fetch_array($rResult, SQLITE_ASSOC);
                $mResult = $row['time_update'];
            }
            else{
                $mResult = FALSE;
            }
            
            return $mResult;
        }
        
        function close(){
            $this->__destruct();
            unset($this);
        }

    }
}
else{
    //データ関連であるため、あえて表示
    die("クラス'cData'がすでに定義されています。");
}
?>